package com.nodecollege.cloud.service.impl;

import com.nodecollege.cloud.common.constants.NCConstants;
import com.nodecollege.cloud.common.exception.UpmsException;
import com.nodecollege.cloud.common.model.BindVO;
import com.nodecollege.cloud.common.model.QueryVO;
import com.nodecollege.cloud.common.model.po.UpmsAppRole;
import com.nodecollege.cloud.common.model.po.UpmsAppRoleResource;
import com.nodecollege.cloud.common.utils.NCUtils;
import com.nodecollege.cloud.common.utils.RedisUtils;
import com.nodecollege.cloud.dao.mapper.UpmsAppRoleMapper;
import com.nodecollege.cloud.dao.mapper.UpmsAppRoleResourceMapper;
import com.nodecollege.cloud.service.AppRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 应用预制角色
 *
 * @author LC
 * @date 2020/1/9 18:47
 */
@Service
public class AppRoleServiceImpl implements AppRoleService {

    @Autowired
    private UpmsAppRoleMapper upmsAppRoleMapper;

    @Autowired
    private UpmsAppRoleResourceMapper upmsAppRoleResourceMapper;

    @Autowired
    private RedisUtils redisUtils;

    /**
     * 查询应用预制角色列表
     *
     * @param query
     * @return
     */
    @Override
    public List<UpmsAppRole> getAppRoleListCache(QueryVO<UpmsAppRole> query) {
        NCUtils.nullOrEmptyThrow(query.getData(), new UpmsException("", "参数错误"));
        List<UpmsAppRole> appRoleList = redisUtils.getList("upms:allAppRoleList", UpmsAppRole.class);
        if (appRoleList == null) {
            appRoleList = upmsAppRoleMapper.selectListByMap(null);
            redisUtils.set("upms:allAppRoleList", appRoleList, 60 * 60);
        }
        if (NCUtils.isNotNullOrNotEmpty(query.getLongList())) {
            List<UpmsAppRole> returnList = new ArrayList<>();
            for (int i = 0; i < query.getLongList().size(); i++) {
                for (int j = 0; j < appRoleList.size(); j++) {
                    if (query.getLongList().get(i).equals(appRoleList.get(j).getAppId())) {
                        returnList.add(appRoleList.get(j));
                    }
                }
            }
            return returnList;
        }
        if (query.getData() != null && query.getData().getAppId() != null) {
            List<UpmsAppRole> returnList = new ArrayList<>();
            for (int j = 0; j < appRoleList.size(); j++) {
                if (query.getData().getAppId().equals(appRoleList.get(j).getAppId())) {
                    returnList.add(appRoleList.get(j));
                }
            }
            return returnList;
        }
        return appRoleList;
    }

    /**
     * 清除应用角色缓存
     */
    @Override
    public void clearAppRoleListCache() {
        redisUtils.delete("upms:allAppRoleList");
    }

    /**
     * 添加应用预制角色
     *
     * @param appRole
     */
    @Override
    public void addAppRole(UpmsAppRole appRole) {
        NCUtils.nullOrEmptyThrow(appRole.getRoleCode(), new UpmsException("-1", "应用角色代码必填！"));
        NCUtils.nullOrEmptyThrow(appRole.getRoleName(), new UpmsException("-1", "应用角色名称必填！"));

        UpmsAppRole queryRole = new UpmsAppRole();
        queryRole.setRoleCode(appRole.getRoleCode());
        List<UpmsAppRole> list = upmsAppRoleMapper.selectListByMap(new QueryVO<>(queryRole).toMap());
        NCUtils.notNullOrNotEmptyThrow(list, new UpmsException("", "该角色代码已存在！"));

        appRole.setState(NCConstants.INT_1);
        appRole.setCreateTime(new Date());

        upmsAppRoleMapper.insertSelective(appRole);
        clearAppRoleListCache();
    }

    /**
     * 更新应用预制角色
     *
     * @param appRole
     */
    @Override
    public void updateAppRole(UpmsAppRole appRole) {
        NCUtils.nullOrEmptyThrow(appRole.getAppRoleId(), new UpmsException("-1", "应用角色id必填！"));

        UpmsAppRole exist = upmsAppRoleMapper.selectByPrimaryKey(appRole.getAppRoleId());
        NCUtils.nullOrEmptyThrow(exist, new UpmsException("-1", "该引用角色不存在！"));

        UpmsAppRole queryRole = new UpmsAppRole();
        queryRole.setRoleCode(appRole.getRoleCode());
        List<UpmsAppRole> list = upmsAppRoleMapper.selectListByMap(new QueryVO<>(queryRole).toMap());
        if (list.size() == 1 && !list.get(0).getAppRoleId().equals(appRole.getAppRoleId())) {
            throw new UpmsException("-1", "该角色代码已存在！");
        }

        appRole.setState(exist.getState());
        appRole.setCreateTime(null);

        upmsAppRoleMapper.updateByPrimaryKeySelective(appRole);
        clearAppRoleListCache();
    }

    /**
     * 删除应用预制角色
     *
     * @param appRole
     */
    @Override
    public void delAppRole(UpmsAppRole appRole) {
        NCUtils.nullOrEmptyThrow(appRole.getAppRoleId(), new UpmsException("-1", "应用角色id必填！"));

        UpmsAppRole exist = upmsAppRoleMapper.selectByPrimaryKey(appRole.getAppRoleId());
        NCUtils.nullOrEmptyThrow(exist, new UpmsException("-1", "该应用角色不存在！"));
        if (exist.getState().equals(NCConstants.INT_0)) {
            throw new UpmsException("-1", "该应用角色不能删除！");
        }

        UpmsAppRole delRole = new UpmsAppRole();
        delRole.setState(NCConstants.INT_NEGATIVE_1);
        delRole.setAppRoleId(appRole.getAppRoleId());
        upmsAppRoleMapper.updateByPrimaryKeySelective(delRole);
        clearAppRoleListCache();
    }

    /**
     * 查询应用角色绑定的资源列表
     *
     * @param resource
     * @return
     */
    @Override
    public List<UpmsAppRoleResource> getAppRoleResourceListCache(UpmsAppRoleResource resource) {
        List<UpmsAppRoleResource> list = redisUtils.getList("upms:appRoleResourceList:"
                + resource.getAppRoleId(), UpmsAppRoleResource.class);
        if (list == null) {
            list = upmsAppRoleResourceMapper.selectByAppRoleId(resource.getAppRoleId());
            redisUtils.set("upms:appRoleResourceList:" + resource.getAppRoleId(), list, 60 * 60);
        }
        return list;
    }

    /**
     * 清除应用资源id
     *
     * @param appRoleId
     */
    @Override
    public void clearAppRoleResourceListCache(Long appRoleId) {
        if (appRoleId != null) {
            redisUtils.delete("upms:appRoleResourceList:" + appRoleId);
        } else {
            redisUtils.delete(redisUtils.keys("upms:appRoleResourceList::*"));
        }
    }

    /**
     * 绑定应用角色资源
     *
     * @param bindVO
     */
    @Override
    public void bindAppRoleResource(BindVO bindVO) {
        if (NCUtils.isNullOrEmpty(bindVO.getSourceIds()) || NCUtils.isNullOrEmpty(bindVO.getTargetIds())) {
            throw new UpmsException("-1", "绑定入参有误！");
        }

        // 已绑定的数据
        UpmsAppRoleResource query = new UpmsAppRoleResource();
        query.setAppRoleId(bindVO.getSourceIds().get(0));
        List<UpmsAppRoleResource> exList = getAppRoleResourceListCache(query);

        // 最终保留的数据
        List<UpmsAppRoleResource> endList = new ArrayList<>(bindVO.getSourceIds().size() * bindVO.getTargetIds().size());
        bindVO.getSourceIds().forEach(appRoleId -> {
            bindVO.getTargetIds().forEach(appResourceId -> {
                UpmsAppRoleResource end = new UpmsAppRoleResource();
                end.setAppResourceId(appResourceId);
                end.setAppRoleId(appRoleId);
                endList.add(end);
            });
        });

        // 取消绑定的数据
        exList.forEach(ex -> {
            Boolean delFlag = true;
            for (int i = 0; i < endList.size(); i++) {
                if (ex.getAppRoleId().equals(endList.get(i).getAppRoleId())
                        && ex.getAppResourceId().equals(endList.get(i).getAppResourceId())) {
                    delFlag = false;
                    break;
                }
            }
            if (delFlag) {
                upmsAppRoleResourceMapper.deleteByPrimaryKey(ex.getAppRoleResourceId());
            }
        });

        // 新增绑定的数据
        endList.forEach(end -> {
            Boolean addFlag = true;
            for (int i = 0; i < exList.size(); i++) {
                if (end.getAppRoleId().equals(exList.get(i).getAppRoleId())
                        && end.getAppResourceId().equals(exList.get(i).getAppResourceId())) {
                    addFlag = false;
                    break;
                }
            }
            if (addFlag) {
                upmsAppRoleResourceMapper.insert(end);
            }
        });
        clearAppRoleResourceListCache(query.getAppRoleId());
    }

}
